package com.myjianzhu.zzt88.exercise.java.thread;

import java.util.LinkedList;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ProductAndCustomer {

    //阻塞队列
    private static BlockingDeque<String> wharehouse;

    public static void main(String[] args) {
        testReentrantLock();
//        testBlockingDeque();
    }

    /*-----------------------帅气的分割线-------------------------------*/


    static void testReentrantLock() {
        final WhareHouseManager manager = new WhareHouseManager(2);
        Thread productor = new Thread(() -> {
            while (true)
                try {
                    System.out.println("product black cloth");
                    Thread.sleep(1000);
                    manager.push("Black Clothes");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        });
        Thread productor2 = new Thread(() -> {
            while (true)
                try {
                    System.out.println("product green cloth");
                    Thread.sleep(1000);
                    manager.push("Green Clothes");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        });
        Thread productor3 = new Thread(() -> {
            while (true)
                try {
                    System.out.println("product red cloth");
                    Thread.sleep(1000);
                    manager.push("Red Clothes");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        });
        Thread customer = new Thread(() -> {
            while (true)
                try {
                    String product = manager.peek();
                    Thread.sleep(1000);
                    System.out.println("custom cloth " + product);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        });
        Thread customer2 = new Thread(() -> {
            while (true)
                try {
                    String product = manager.peek();
                    Thread.sleep(1000);
                    System.out.println("custom cloth " + product);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        });
        Thread customer3 = new Thread(() -> {
            while (true)
                try {
                    String product = manager.peek();
                    Thread.sleep(1000);
                    System.out.println("custom cloth " + product);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        });

        productor.start();
        productor2.start();
        productor3.start();
        customer.start();
        customer2.start();
        customer3.start();
    }

    static class WhareHouseManager {
        private LinkedList<String> list = new LinkedList<>();
        private int maxCount = 10;
        ReentrantLock lock = new ReentrantLock();
        private Condition notFull;
        private Condition notEmpty;


        WhareHouseManager(int maxCount) {
            this.maxCount = maxCount;
            notFull = lock.newCondition();
            notEmpty = lock.newCondition();
        }

        public void push(String product) throws InterruptedException {
            try {
                lock.lock();
                while (maxCount == list.size()) {
                    notFull.await();
                }
                list.add(product);
                System.out.println("list put product " + product);
                notEmpty.signalAll();

            } finally {
                lock.unlock();
            }
        }

        public String peek() throws InterruptedException {
            try {
                lock.lock();
                while (list.size() == 0) {
                    notEmpty.await();
                }
                String product = list.remove(0);
                System.out.println("list remove product " + product);
                notFull.signalAll();
                return product;
            } finally {
                lock.unlock();
            }
        }
    }





    /*-----------------------帅气的分割线-------------------------------*/


    /**
     * 使用BlockingDeque实现生产者消费者线程问题
     */
    static void testBlockingDeque() {
        wharehouse = new LinkedBlockingDeque<>();
        new Customer(wharehouse, "LEE").start();
        new Customer(wharehouse, "WANG").start();
        new Customer(wharehouse, "ZAO").start();
        new Customer(wharehouse, "SUN").start();

        new Product(wharehouse, "RED").start();
        new Product(wharehouse, "YELLOW").start();
        new Product(wharehouse, "BLUE").start();
        new Product(wharehouse, "GREEN").start();
    }

    static class Product extends Thread {
        private BlockingDeque<String> wharehouse;
        private String color;

        public Product(BlockingDeque<String> wharehouse, String color) {
            this.color = color;
            this.wharehouse = wharehouse;
        }

        @Override
        public void run() {

            System.out.println("product " + color);

            wharehouse.push(color);


        }
    }

    static class Customer extends Thread {
        private BlockingDeque<String> wharehouse;
        private String customerName;


        public Customer(BlockingDeque wharehouse, String customerName) {
            this.wharehouse = wharehouse;
            this.customerName = customerName;
        }

        @Override
        public void run() {
            String color = null;
            try {
                color = wharehouse.take();
                System.out.println(customerName + " consume " + color);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}
